﻿/*****************************************************
 * 本类库的核心系 JNTemplate
 * (C) JNTemplate 2011
 * 作者：翅膀的初衷 QQ:4585839
 * 网址：http://www.JiNianNet.com
 *****************************************************/

using System;
using System.Collections.Generic;
using JinianNet.JNTemplate.Process.Element;

namespace JinianNet.JNTemplate.Process
{
    public class TemplateLexer
    {
        private string _document;
        private List<Token> _element;
        private int _index;
        private int _start;
        private bool _isStart;
        public TemplateLexer()
        {
            Reset();
        }
        public TemplateLexer(string document)
        {
            this._document = document;
            Reset();
        }
        public void Reset()
        {
            this._element = new List<Token>();
            this._index = 0;
            this._start = 0;
            this._isStart = false;
        }
        public string Docuemnt
        {
            get { return this._document; }
            set { this._document = value; }
        }
        public List<Token> FindAll()
        {
            if (!string.IsNullOrEmpty(this._document))
                while (!IsEnd())
                    this._element.Add(Next());
            return this._element;
        }

        public Token Next()
        {
            while (!IsEnd())
            {
                if (!_isStart && IsTagBegin())
                {
                    if (this._start == this._index)
                    {
                        this._isStart = true;
                        this._index += 2;
                        this._start = this._index;
                    }
                    else
                    {
                        Token token;
                        token = new Token(TokenKind.Text, Current());
                        this._isStart = true;
                        this._index += 2;
                        this._start = this._index;
                        return token;
                    }
                }
                else if (IsTagClose())
                {
                    if (this._isStart)
                    {
                        this._isStart = false;
                        if (this._start < this._index)
                        {
                            Token token = new Token(TokenKind.Tag, Current());
                            this._index++;
                            this._start = this._index;
                            return token;
                        }
                    }
                    this._index++;
                }
                else
                {
                    this._index++;
                }
            }
            if (this._start < this._index)
                return new Token(TokenKind.Text, Current());
            else
                return new Token(TokenKind.Text, string.Empty);
        }

        //public Token Next()
        //{
        //    while (!IsEnd())
        //    {
        //        if (IsTagBegin())
        //        {
        //            if (this._start == this._index)
        //            {
        //                this._isStart = true;
        //                this._index += 2;
        //                this._start = this._index;
        //            }
        //            else
        //            {
        //                Token token;
        //                if (_isStart)
        //                    token = new Token(TokenKind.Tag, Current());
        //                else
        //                    token = new Token(TokenKind.Text, Current());
        //                this._isStart = true;
        //                this._index += 2;
        //                this._start = this._index;
        //                return token;
        //            }
        //        }
        //        else if (IsTagClose())
        //        {
        //            if (this._isStart)
        //            {
        //                this._isStart = false;
        //                if (this._start < this._index)
        //                {
        //                    Token token = new Token(TokenKind.Tag, Current());
        //                    this._index++;
        //                    this._start = this._index;
        //                    return token;
        //                }
        //            }
        //            this._index++;
        //        }
        //        else
        //        {
        //            this._index++;
        //        }
        //    }
        //    if (this._start < this._index)
        //        return new Token(TokenKind.Text, Current());
        //    else
        //        return new Token(TokenKind.Text, string.Empty);
        //}
        public string Current()
        {
            return this._document.Substring(this._start, this._index - this._start);
        }
        public bool IsTagBegin()
        {
            if (this._document.Length > this._index + 3)
                return this._document[this._index] == '#' && this._document[this._index + 1] == '{';
            return false;
        }
        public bool IsTagClose()
        {
            if (this._document.Length >= this._index + 1)
                return this._document[this._index] == '}';
            return false;
        }
        public bool IsEnd()
        {
            return this._index >= this._document.Length;
        }
    }
}
